﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WRJClient.UI.Map
{

    public abstract class JsonCreationConverter<T> : JsonConverter
    {
        protected abstract T Create(Type objectType, JObject jsonObject);
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            T target = default(T);
            try
            {
                target = Create(objectType, jsonObject);
                serializer.Populate(jsonObject.CreateReader(), target);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            return target;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    public class BaseMarkerInfoConverter : JsonCreationConverter<BaseSymbolInfo>
    {
        protected override BaseSymbolInfo Create(Type objectType, JObject jsonObject)
        {
            string className = jsonObject["ClassName"].ToString();
            string fullClassName = string.Format("WRJClient.UI.Map.{0}", className);
            return Assembly.GetExecutingAssembly().CreateInstance(fullClassName) as BaseSymbolInfo;
        }
    }
    public sealed class SymbolHelper
    {
        private string _filepath = @"Resource\Data\markerdefine.json";

        private List<BaseSymbolInfo> _infolist = new List<BaseSymbolInfo>();

        private static readonly SymbolHelper _instance = new SymbolHelper();
        public static SymbolHelper Instance { get { return _instance; } }
        private SymbolHelper()
        {
            Init();
        }
        private void Init()
        {
            try
            {
                string jsonstring = File.ReadAllText(_filepath);
                _infolist = JsonConvert.DeserializeObject<List<BaseSymbolInfo>>(jsonstring, new BaseMarkerInfoConverter());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

        public PictureMarkerSymbolInfo GetPictureMarkerSymbolInfo(Type typeName, string type = null, string status = null)
        {
            if (_infolist != null)
            {
                return _infolist.Find(i => i.TypeName == typeName.Name && i.Type == type && i.Status == status && i.ClassName == "PictureMarkerSymbolInfo") as PictureMarkerSymbolInfo;
            }
            return null;
        }
        public FillSymbolInfo GetFillSymbolInfo(Type typeName, string type = null, string status = null)
        {
            if (_infolist != null)
            {
                return _infolist.Find(i => i.TypeName == typeName.Name && i.Type == type && i.Status == status && i.ClassName == "FillSymbolInfo") as FillSymbolInfo;
            }
            return null;
        }
        public LineSymbolInfo GetLineSymbolInfo(Type typeName, string type = null, string status = null)
        {
            if (_infolist != null)
            {
                return _infolist.Find(i => i.TypeName == typeName.Name && i.Type == type && i.Status == status && i.ClassName == "LineSymbolInfo") as LineSymbolInfo;
            }
            return null;
        }

        public TextSymbolInfo GetTextSymbolInfo(Type typeName)
        {
            TextSymbolInfo textSymbolInfo = null;
            if (_infolist != null)
            {
                textSymbolInfo = _infolist.Find(i => i.TypeName == typeName.Name && i.ClassName == "TextSymbolInfo") as TextSymbolInfo;
                if (textSymbolInfo == null)
                {
                    textSymbolInfo = _infolist.Find(i => i.TypeName == "Base" && i.ClassName == "TextSymbolInfo") as TextSymbolInfo;
                }
            }
            return textSymbolInfo;
        }

    }
}
